#include <pspsdk.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <psprtc.h>
#include <pspgu.h>
#include <pspgum.h>
#include <stdlib.h>
#include <pspsuspend.h>
#include <psppower.h>
#include <psputils.h>
#include <systemctrl.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <vlf.h>

#include "lrecovery.h"


//--------------------------------------------------------------------------------------------------------------

PSP_MODULE_INFO("LRMInstall", 1, 1, 0);	
PSP_MAIN_THREAD_ATTR(0);

int MainMenu(int sel);
void *buf;

VlfText ttext;

//--------------------------------------------------------------------------------------------------------------

void Error(char *text)
{
	vlfGuiMessageDialog(text, VLF_MD_TYPE_ERROR | VLF_MD_BUTTONS_NONE);
}

void Success(char *text)
{
	vlfGuiMessageDialog(text, VLF_MD_TYPE_NORMAL | VLF_MD_BUTTONS_NONE);
}

int CopyFile(char *input, char *output)
{
SceUID i = sceIoOpen(input, PSP_O_RDONLY, 0777);

if (i < 0)
return -1;

sceIoRemove(output);

SceUID o = sceIoOpen(output, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);

if (o < 0)
return -1;

int read;

while ((read = sceIoRead(i, buf, 16384)) > 0)
{
sceIoWrite(o, buf, read);
}

sceIoClose(i);
sceIoClose(o);

return 0;
}

int WriteFile(char *file, void *buf, int size)
{
    SceUID write;
	int written = 0;
	
	write = sceIoOpen(file, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
    if(write >= 0)
    {
        sceIoWrite(write, buf, size);
        sceIoClose(write);
    }
	else
	{
		written = -1;
	}
	return written;
}

int Install()
{
	int written = 0;
	
	sceIoUnassign("flash0:");
	sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0);

	written = CopyFile("flash0:/vsh/module/recovery.prx", "flash0:/vsh/module/orecovery.prx");
	if (written < 0)
	{
	return written;
	}
	
	written = WriteFile("flash0:/vsh/module/recovery.prx", (void*)lrecovery, size_lrecovery);
	if (written < 0)
	{
		return written;			
	}
	
	return written;
}

int Restore()
{
	int restore = 0;
	
	sceIoUnassign("flash0:");
	sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0);

	restore = sceIoRemove("flash0:/vsh/module/recovery.prx");
	if (restore < 0)
	{
	return restore;
	}
	
	restore = sceIoRename("flash0:/vsh/module/orecovery.prx", "flash0:/vsh/module/recovery.prx");
	if (restore < 0)
	{
	return restore;
	}

	return restore;
}

//--------------------------------------------------------------------------------------------------------------

int OnMainMenuSelect(int sel)
{
	int done;
	int rest;
	
	switch (sel)
	{
		case 0:
		{
			vlfGuiCancelLateralMenu();
			vlfGuiRemoveText(ttext);
			
			done = Install();
			if (done < 0)
			{
				Error("Installation failed!\nPlease redownload LRMInstaller.\n");
				sceKernelExitGame();
			}
			else
			{
				Success("Installation successful!");
				sceKernelExitGame();
			}
			
			return 0;
		}
		break;
		
		case 1:
		{
			vlfGuiCancelLateralMenu();
			vlfGuiRemoveText(ttext);
			
			rest = Restore();
			if (rest < 0)
			{
				Error("Restore failed!\nThe original recovery data are corrupt!\n");
				sceKernelExitGame();
			}
			else
			{
				Success("Restore successful!");
				sceKernelExitGame();
			}
			
            return 0;
		}
		break;
		
		case 2:
		{
			sceKernelExitGame();			
		}
		break;
		
	}
	
	return 0;
}

int MainMenu(int sel)
{
	char *items[] =
	{
		"Install",
		"Restore",
		"Exit"
	};
 
	vlfGuiLateralMenu(2, items, sel, OnMainMenuSelect, 100);
	return 0;
};

//--------------------------------------------------------------------------------------------------------------
		
int Title()
{
	vlfGuiSetModelSystem();
	vlfGuiSetSystemColor(26);
	vlfGuiSetBackgroundPlane(0xff999999);
	ttext = vlfGuiAddText(5, 5, "Lite Recovery Menu v1 Installer\nby Cha0z (alias Co$m0)\n\n");
	vlfGuiSetTextFontSize(ttext, 0.75f);
	vlfGuiAddBatteryIconSystem(10*1000*1000);
	vlfGuiAddClock();
	
	MainMenu(0);
	
	while (1)
		vlfGuiDrawFrame();
	
	return 0;
};